<?php
namespace fankers\helper;

class Http
{

    private $defaultOptions = [
        CURLOPT_TIMEOUT => 35,
        CURLOPT_HEADER =>false,
        CURLOPT_NOBODY => false,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_FAILONERROR => false,
        CURLOPT_SSL_VERIFYPEER => false,
        CURLOPT_SSL_VERIFYHOST => false,
    ];

    
    public function get($url, $param = [], $options = [])
    {
        if( !empty($param) )
        {
            $url .= "?".http_build_query($param);
        }
        return $this->exec($url, [], $options);
    }
    public function post($url, $param, $options = [])
    {
        return $this->exec($url, $param, $options = []);
    }

    public function toJson($param, $encodeOption = JSON_UNESCAPED_UNICODE )
    {
        if( is_array($param) )
        {
            $param = json_encode($param, $encodeOption);
            return $param;
        }
        return $param;  
    }

    public function parseJSON($json)
    {
        if (empty($json)) {
            return false;
        }
        $ret = json_decode($json, true);

        if (JSON_ERROR_NONE !== json_last_error()) {
            throw new \Exception('Failed to parse JSON: '.json_last_error_msg());
        }
        return $ret;
    }

    /**
     * url中的参数转换成字符串
     * @param $params
     * @return array|bool
     */
    public function parseQueryParams($params)
    {
        if (empty($params))
        {
            return false;
        }
        $dataArr = explode('&',trim($params,'&'));

        $returnData = [];
        foreach ($dataArr as $data) {
            $temp = explode('=',$data);
            $returnData[$temp[0]] = $temp[1];
        }
        return $returnData;
    }

    /**
     * 大坑qq数据处理
     * @param $params
     * @return array|mixed
     */
    public function message2array($params)
    {
        $returnArr = [];
        if (strpos($params, "callback") !== false)
        {
            $lpos = strpos($params, "(");
            $rpos = strrpos($params, ")");
            $str  = substr($params, $lpos + 1, $rpos - $lpos -1);

            $returnArr = json_decode($str,true);
        }
        return $returnArr;
    }
    /**
     * 执行curl请求
     * @param $url
     * @param array $post_data
     * @param array $options
     * @return array|mixed
     * @throws HttpException
     */
    public function exec($url, $post_data = [], $options = [])
    {
        $post_options = [];
        if (!empty($post_data)) {
            $post_options = $this->postOptions($post_data);
        }
        $options = $this->mergeOptions($this->defaultOptions, $options, $post_options);
        $ch = curl_init($url);
        curl_setopt_array($ch, $options);
        
        $return = curl_exec($ch);
//        \helper\Log::debug($return,'/tmp/fkk_qq_token_log');
        if (!$return) {
            throw new HttpException(curl_error($ch), curl_errno($ch));
        }

        if ($options[CURLOPT_HEADER]) {
            $headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
            $header = substr($return, 0, $headerSize - 2);
            $header = trim($header);
            $headerData = [];
            foreach (explode("\n", $header) as $row) {
                if (strpos($row, ':') !== false) {
                    list($k, $v) = explode(':', $row, 2);
                    $headerData[$k] = $v;
                } else {
                    $headerData[] = $row;
                }

            }
            $body = substr($return, $headerSize);
            curl_close($ch);
            return ['header' => $headerData, 'body' => $body];
        } else {
            curl_close($ch);
            return $return;
        }
    }

    protected function mergeOptions()
    {
        $args = func_get_args();
        $data = [];
        foreach($args as $options) {
            foreach($options as $k=>$v) {
                $data[$k] = $v;
            }
        }
        return $data;
    }

    protected function postOptions($post_data)
    {
        if (is_array($post_data)) {
            $post_data = $this->buildQuery($post_data);
        }
        return [
            CURLOPT_POST => true,
            CURLOPT_POSTFIELDS => $post_data,
        ];
    }

    protected function buildQuery($data, $prefix = [])
    {
        $query = [];
        foreach($data as $k=>$v)
        {
            array_push($prefix, $k);
            if (is_array($v)) {
                $query = array_merge($query, $this->buildQuery($v, $prefix));
            } else {
                $newkey = $this->buildPrefix($prefix);
                $query[$newkey] = $v;
            }
            array_pop($prefix);
        }
        return $query;
    }

    protected function buildPrefix($prefix)
    {
        $return = '';
        foreach($prefix as $k=>$v)
        {
            if ($k == 0) {
                $return .= $v;
            } else {
                $return .= '['.$v.']';
            }
        }
        return $return;
    }
}
